package sanrenxing.score.dao.impl;

import sanrenxing.score.dao.ScoreDao;
import sanrenxing.score.domain.Score;
import sanrenxing.score.domain.ScoreTo;
import sanrenxing.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 功能:成绩数据层
 * 编写者:黄雄珠
 * 创建时间：2020/9/25 19:12
 * 版本:1.0
 */
public class ScoreDaoImpl implements ScoreDao {
    /**
     * 将成绩实体对象添加到数据库score表中
     *
     * @param score 成绩对象
     * @return 成功添加的行数(1 : 添加成功 ; 0 : 添加失败)
     */
    @Override
    public int add(Score score) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //定义影响行数的变量
        int rows=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="insert into score values(?,?,?,?,?,?)";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setInt(1,score.getScoreId());
            pstmt.setInt(2,score.getCourseId());
            pstmt.setString(3,score.getStuId());
            pstmt.setInt(4,score.getClassId());
            pstmt.setInt(5,score.getPaperId());
            pstmt.setInt(6,score.getGrades());
            //使用预编译语句对象执行SQL语句，返回影响的行数
            rows=pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回影响的行数
        return rows;
    }

    /**
     * 根据成绩编号主键从数据库score表中删除指定成绩数据
     *
     * @param scoreId 成绩编号主键
     * @return 删除影响的行数(1 : 删除成功 ; 0 : 删除失败)
     */
    @Override
    public int delete(int scoreId) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //定义影响行数的变量
        int rows=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="delete from score where scoreId=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setInt(1,scoreId);
            //使用预编译语句对象执行SQL语句，返回影响的行数
            rows=pstmt.executeUpdate();
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回影响的行数
        return rows;
    }

    /**
     * 将成绩对象数据修改到数据库score表中
     *
     * @param score 成绩对象
     * @return 修改影响的行数(1 : 修改成功 ; 0 : 修改失败)
     */
    @Override
    public int update(Score score) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //定义影响行数的变量
        int rows=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="update score set grades=? where scoreId=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setInt(1,score.getGrades());
            pstmt.setInt(2,score.getScoreId());
            //使用预编译语句对象执行SQL语句，返回影响的行数
            rows=pstmt.executeUpdate();
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回影响的行数
        return rows;
    }

    /**
     * 根据成绩编号主键从数据库score表中查找单个成绩
     *
     * @param scoreId 成绩编号主键
     * @return 成绩对象(如果返回null值 ， 表示查找失败)
     */
    @Override
    public Score findById(int scoreId) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回的成绩对象
        Score score=null;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="select scoreId,courseId,stuId,classId,paperId," +
                    "grades from score where scoreId=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setInt(1,scoreId);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            //判断结果集，并把结果集的数据封装到成绩对象中
            if(rs.next()){
                //实例化成绩对象
                score=new Score();
                //把结果集数据赋值给成绩对象各属性
                score.setScoreId(rs.getInt("scoreId"));
                score.setCourseId(rs.getInt("courseId"));
                score.setStuId(rs.getString("stuId"));
                score.setClassId(rs.getInt("classId"));
                score.setPaperId(rs.getInt("paperId"));
                score.setGrades(rs.getInt("grades"));
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //返回成绩对象
        return score;
    }

    /**
     * 查询数据库score表中所有成绩
     *
     * @return 成绩对象集合
     */
    @Override
    public List<Score> findAll() {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回的成绩对象集合
        List<Score> scoreList=new ArrayList<Score>();
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="SELECT s.scoreId scoreId,c.courseName courseName,stu.stuName stuName,cl.className className,s.paperId paperId,s.grades grades FROM" +
                    " score s JOIN course c ON s.courseId=c.courseId JOIN " +
                    "student stu ON s.stuId=stu.stuId JOIN" +
                    "class cl ON s.classId=cl.classId";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            //循环判断结果集，并把结果集的数据封装到成绩对象中
            while(rs.next()){
                //定义成绩对象
                Score score=new Score();
                //把结果集数据赋值给成绩对象各属性
                score.setScoreId(rs.getInt("scoreId"));
//                score.setCourseName(rs.getString("courseName"));
                score.setStuId(rs.getString("stuId"));
                score.setClassId(rs.getInt("classId"));
                score.setPaperId(rs.getInt("paperId"));
                score.setGrades(rs.getInt("grades"));
                //把成绩对象添加成绩集合中
                scoreList.add(score);
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //返回成绩对象集合
        return scoreList;
    }

    /**
     * 从数据库score表中查询指定页的成绩对象集合
     *
     * @param rows  每页的成绩行数
     * @param pages 页数
     * @return 当前页的成绩对象集合
     */
    @Override
    public List<ScoreTo> findByPage(int rows, int pages , String condition) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回的成绩对象集合
        List<ScoreTo> scoreToList=new ArrayList<ScoreTo>();
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="SELECT s.scoreId scoreId,c.courseName courseName,stu.stuName stuName,cl.className className,s.paperId paperId,s.grades grades FROM score s JOIN course c ON s.courseId=c.courseId JOIN " +
                    "student stu ON s.stuId=stu.stuId JOIN " +
                    "class cl ON s.classId=cl.classId where 1=1 "+condition+"  limit ?,?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //给分页语句占位符赋值
            //分页语句：select * from 表名 limits (pages-1)*rows,rows
            pstmt.setInt(1,(pages-1)*rows);
            pstmt.setInt(2,rows);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            //循环判断结果集，并把结果集的数据封装到成绩对象中
            while(rs.next()){
                //定义成绩对象
                ScoreTo scoreTo=new ScoreTo();
                //把结果集数据赋值给成绩对象各属性
                scoreTo.setScoreId(rs.getInt("scoreId"));
                scoreTo.setCourseName(rs.getString("courseName"));
                scoreTo.setStuName(rs.getString("stuName"));
                scoreTo.setClassName(rs.getString("className"));
                scoreTo.setPaperId(rs.getInt("paperId"));
                scoreTo.setGrades(rs.getInt("grades"));
                //把成绩对象添加成绩集合scoreToList中
                scoreToList.add(scoreTo);
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //返回成绩对象集合
        return scoreToList;
    }

    /**
     * 统计数据库score表中记录总数
     *
     * @return 成绩表中记录总数
     */
    @Override
    public int count() {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回表中总数据行数
        int rowCount=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="select count(*) as scorecount from score";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //使用预编译语句对象执行SQL语句，返回结果集合
            rs=pstmt.executeQuery();
            //判断结果集，并获得总行数
            if(rs.next()){
                //如果统计行数时没有指定别名，则用数字0作为参数
                rowCount=rs.getInt("scorecount");
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回表中数据总行数
        return rowCount;
    }


    /**
     * 条件统计
     *
     * @param condition 条件
     * @return
     */
    @Override
    public int count(String condition) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;
        //定义返回表中总数据行数
        int rowCount=0;
        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="select count(*) as scorecount from score s where 1=1 "+condition;
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //使用预编译语句对象执行SQL语句，返回结果集合
            rs=pstmt.executeQuery();
            //判断结果集，并获得总行数
            if(rs.next()){
                //定义rowCount变量接收结果集中的scorecount
                rowCount=rs.getInt("scorecount");
            }
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
        //返回表中数据总行数
        return rowCount;
    }

    /**
     * 获取查询条件
     *
     * @param score 成绩对象
     * @return 条件字符串
     */
    @Override
    public String getCondition(Score score) {
        //定义查询条件字符串，初值为带空格的字符串(注意后续条件中的空格)
        String condition=" ";
        //如果成绩对象为空，则直接返回空字符串
        if(score==null){
            return condition;
        }
        //如果成绩编号不为0
        if(score.getScoreId()!=0){
            condition += " and s.scoreId="+score.getScoreId();
        }
        //如果成绩姓名不为空(字符串匹配模糊查询)
        if(score.getCourseId()!=0){
            condition += " and s.courseId="+score.getCourseId();
        }
        //如果工种不为空
        if(score.getStuId()!=null && score.getStuId().trim().length()!=0){
            condition += " and s.stuId like '%"+score.getStuId()+"%' ";
        }
        //如果存在管理者编号
        if(score.getClassId()!=0){
            condition += " and s.classId="+score.getClassId();
        }
        //如果薪水不为空
        if(score.getPaperId()!=0){
            condition += " and s.paperId="+score.getPaperId();
        }
        //如果津贴不为空
        if(score.getGrades()!=0){
            condition += " and s.grades="+score.getGrades();
        }
        //返回条件字符串
        return condition;
    }

    @Override
    public int findClassName(String className) {
        //定义int类型的班级编号classId
        int classId;
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;


        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="SELECT  classId FROM class where className=? ";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setString(1,className);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            if (rs.next()){
                //定义classId变量接收结果集中的班级编号classId
                classId=rs.getInt("classId");
                //返回班级编号变量
                return classId;
            }

        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        return 0;
    }

    /**
     * 通过学员名字查询学员编号
     *
     * @param stuName
     * @return
     */
    @Override
    public String findStuName(String stuName) {
        //定义字符串类型的stuId
        String stuId;
        //声明数据库链接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;


        try {
            //实例化数据库链接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="SELECT  stuId FROM student where stuName=? ";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setString(1,stuName);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            if (rs.next()){
                //用stuId变量接收学员结果集中的学员编号
                stuId=rs.getString("stuId");
                //返回学员编号
                return stuId;
            }

        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        return null;
    }

    /**
     * 通过课程名称查询课程编号
     *
     * @param courseName
     * @return
     */
    @Override
    public int findCourseName(String courseName) {
        //定义int类型的courseId变量
        int courseId;
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;

        try {
            //实例化数据库链接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="SELECT  courseId FROM course where courseName=? ";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setString(1,courseName);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            if (rs.next()){
                //用courseId变量接收结果集中的courseId
                courseId=rs.getInt("courseId");
                //返回courseId
                return courseId;
            }

        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        return 0;
    }

    /**
     * 通过成绩编号查询学员编号
     *
     * @param scoreId
     * @return
     */
    @Override
    public String findStuId(int scoreId) {
        //字符串类型的stuId
        String stuId;
        //声明数据库链接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;
        //声明结果集对象
        ResultSet rs=null;

        try {
            //实例化数据库链接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="SELECT  stuId FROM score where scoreId=? ";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setInt(1,scoreId);
            //使用预编译语句对象执行SQL语句，返回结果集
            rs=pstmt.executeQuery();
            if (rs.next()){
                //使用stuId变量接收结果集中的学员编号
                stuId=rs.getString("stuId");
                //返回学员编号
                return stuId;
            }

        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        }finally {
            //关闭/释放资源
            JdbcUtils.close(rs,pstmt,conn);
        }
        //返回null
        return null;
    }

    /**
     * 修改学员成绩为60以上  则删除补考学员的信息
     *
     * @param stuId
     */
    @Override
    public void deleteGrades(String stuId) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;

        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="delete from reexams where stuId=?";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setString(1,stuId);
            //使用预编译语句对象执行SQL语句，返回影响的行数
            pstmt.executeUpdate();
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }

    }

    /**
     * 添加补考信息
     *
     * @param stuId
     * @param courseId
     */
    @Override
    public void addReexamsMsg(String stuId, int courseId) {
        //声明数据库连接对象
        Connection conn=null;
        //声明预编译语句对象
        PreparedStatement pstmt=null;

        try {
            //实例化数据库连接对象
            conn= JdbcUtils.getConnection();
            //编写SQL语句字符串
            String sql="INSERT INTO reexams(stuId,courseId) VALUES(?,?)";
            //实例化预编译语句对象
            pstmt=conn.prepareStatement(sql);
            //设置SQL语句中占位符赋值
            pstmt.setString(1,stuId);
            pstmt.setInt(2,courseId);
            //使用预编译语句对象执行SQL语句，返回影响的行数
            pstmt.executeUpdate();
        } catch (SQLException e) {
            //抛出运行时异常
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            //关闭/释放资源
            JdbcUtils.close(null,pstmt,conn);
        }
    }


}
